{
  lib,
  nixSystemToRustTargets,
  writeShellScriptBin,
  nix2container,
  lre,
  rust-toolchains ? [lre.stable-rust lre.nightly-rust],
}: let
  copyright = ''
    # Copyright 2024 The NativeLink Authors. All rights reserved.
    #
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    #
    #    http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.

    # This file is @generated by lre-rs.
  '';

  systems = [
    "aarch64-darwin"
    "aarch64-linux"
    "x86_64-darwin"
    "x86_64-linux"
  ];
  channels = [
    "stable"
    "nightly"
  ];

  makeRepoDefinition = system: channel: ''
    ${" "}   new_local_repository(
    ${" "}       name = "lre-rs-${channel}-${system}",
    ${" "}       build_file = "@local-remote-execution//rust:${system}.BUILD.bazel",
    ${" "}       path = "$(nix eval .#packages.${system}.${channel}-rust.outPath --raw)",
    ${" "}   )
  '';

  allRepoDefinitions = lib.concatStrings (lib.flatten (
    map (system: map (channel: makeRepoDefinition system channel) channels) systems
  ));

  buildFile = system: let
    rustTargets = nixSystemToRustTargets.${system};

    # Generate select entry for a target
    mkSelectEntry = target: ''
      ${" "}       "@local-remote-execution//rust/triple:${target}": glob([
      ${" "}           "bin/*.so",
      ${" "}           "lib/*.so",
      ${" "}           "lib/rustlib/${target}/codegen-backends/*.so",
      ${" "}           "lib/rustlib/${target}/bin/rust-lld",
      ${" "}           "lib/rustlib/${target}/lib/*.so",
      ${" "}       ], allow_empty = True),'';

    # Generate stdlib select entry for a target
    mkStdlibSelectEntry = target:
      ''
        ${" "}       "@local-remote-execution//rust/triple:${target}": glob([
        ${" "}           "lib/rustlib/${target}/lib/*.rlib",
        ${" "}           "lib/rustlib/${target}/lib/*.so",
        ${" "}           "lib/rustlib/${target}/lib/*.a",''
      + (lib.optionalString (builtins.match ".*-musl" target != null)
        ''${"\n "}           "lib/rustlib/${target}/lib/self-contained/**",'')
      + ''${"\n "}       ], allow_empty = True),'';

    selectEntries = builtins.concatStringsSep "\n" (map mkSelectEntry rustTargets);
    stdlibSelectEntries = builtins.concatStringsSep "\n" (map mkStdlibSelectEntry rustTargets);
  in ''
    ${copyright}
    """Tool repository for lre-rs executing on ${system}."""

    load("@rules_rust//rust:toolchain.bzl", "rust_stdlib_filegroup")

    [
        filegroup(
            name = tool,
            srcs = [
                "bin/{}".format(tool),
            ],
            visibility = ["//visibility:public"],
        )
        for tool in [
            "rustc",
            "rustfmt",
            "cargo",
            "cargo-clippy",
            "clippy-driver",
            "rustdoc",
        ]
    ]

    filegroup(
        name = "rustc_lib",
        srcs = select({
    ${selectEntries}
        }),
        visibility = ["//visibility:public"],
    )

    rust_stdlib_filegroup(
        name = "rust_std",
        srcs = select({
    ${stdlibSelectEntries}
        }),
        visibility = ["//visibility:public"],
    )'';

  lre-rs-configs-gen = writeShellScriptBin "lre-rs" ''
    set -euo pipefail

    SRC_ROOT=$(git rev-parse --show-toplevel)/local-remote-execution

    cd "''${SRC_ROOT}"

    cat > ''${SRC_ROOT}/rust/extension.bzl << EOF
    ${copyright}
    """Module extension to register different lre-rs tool repositories."""

    load("@bazel_tools//tools/build_defs/repo:local.bzl", "new_local_repository")

    # TODO(palfrey): Using module extensions here isn't optimal as it doesn't
    #                    allow overriding tools via environment variables.
    #                    Unfortunately rules_rust's rust_toolchain currently
    #                    requires tools to be declared via labels to filegroups,
    #                    so we need the new_local_repository approach here.
    #                    Add support for raw strings to rules_rust upstream so
    #                    that we can remove this module extension entirely.

    def _lre_rs_impl(_mctx):
    ${allRepoDefinitions}
    lre_rs = module_extension(implementation = _lre_rs_impl)
    EOF

    cat > ''${SRC_ROOT}/rust/platforms/BUILD.bazel << EOF
    ${copyright}
    # Some toolchains, like the darwin ones, don't have an actual container image.
    # We still map them to the output of the tag of the corresponding theoretical
    # worker image so that bare metal metal workers can advertise exact
    # exec_properties to schedulers.

    platform(
        name = "aarch64-apple-darwin",
        exec_properties = {
            # nix eval .#packages.aarch64-darwin.nativelink-worker-lre-rs.imageTag
            "lre-rs": $(nix eval .#packages.aarch64-darwin.nativelink-worker-lre-rs.imageTag),
        },
        parents = ["@local-remote-execution//platforms:aarch64-darwin"],
    )

    platform(
        name = "aarch64-unknown-linux-gnu",
        constraint_values = ["@local-remote-execution//libc:glibc"],
        exec_properties = {
            # nix eval .#packages.aarch64-linux.nativelink-worker-lre-rs.imageTag
            "lre-rs": $(nix eval .#packages.aarch64-linux.nativelink-worker-lre-rs.imageTag),
        },
        parents = ["@local-remote-execution//platforms:aarch64-linux"],
    )

    platform(
        name = "aarch64-unknown-linux-musl",
        constraint_values = ["@local-remote-execution//libc:musl"],
        exec_properties = {
            # nix eval .#packages.aarch64-linux.nativelink-worker-lre-rs.imageTag
            "lre-rs": $(nix eval .#packages.aarch64-linux.nativelink-worker-lre-rs.imageTag),
        },
        parents = ["@local-remote-execution//platforms:aarch64-linux"],
    )

    platform(
        name = "x86_64-apple-darwin",
        exec_properties = {
            # nix eval .#packages.x86_64-darwin.nativelink-worker-lre-rs.imageTag
            "lre-rs": $(nix eval .#packages.x86_64-darwin.nativelink-worker-lre-rs.imageTag),
        },
        parents = ["@local-remote-execution//platforms:x86_64-darwin"],
    )

    platform(
        name = "x86_64-unknown-linux-gnu",
        constraint_values = ["@local-remote-execution//libc:glibc"],
        exec_properties = {
            # nix eval .#packages.x86_64-linux.nativelink-worker-lre-rs.imageTag
            "lre-rs": $(nix eval .#packages.x86_64-linux.nativelink-worker-lre-rs.imageTag),
        },
        parents = ["@local-remote-execution//platforms:x86_64-linux"],
    )

    platform(
        name = "x86_64-unknown-linux-musl",
        constraint_values = ["@local-remote-execution//libc:musl"],
        exec_properties = {
            # nix eval .#packages.x86_64-linux.nativelink-worker-lre-rs.imageTag
            "lre-rs": $(nix eval .#packages.x86_64-linux.nativelink-worker-lre-rs.imageTag),
        },
        parents = ["@local-remote-execution//platforms:x86_64-linux"],
    )
    EOF

    cat > ''${SRC_ROOT}/rust/aarch64-darwin.BUILD.bazel << EOF
    ${buildFile "aarch64-darwin"}
    EOF

    cat > ''${SRC_ROOT}/rust/aarch64-linux.BUILD.bazel << EOF
    ${buildFile "aarch64-linux"}
    EOF

    cat > ''${SRC_ROOT}/rust/x86_64-darwin.BUILD.bazel << EOF
    ${buildFile "x86_64-darwin"}
    EOF

    cat > ''${SRC_ROOT}/rust/x86_64-linux.BUILD.bazel << EOF
    ${buildFile "x86_64-linux"}
    EOF'';

  Env =
    # Rust requires a functional C++ toolchain.
    lre.lre-cc.image.meta.Env
    ++ [
      # This causes the rust toolchains to be available under `/nix/store/*`
      # paths but not under "generic" paths like `/bin` or `/usr/bin`.
      # This way we're guaranteed to use binary identical toolchains during
      # local and remote execution.
      "RUST=${lib.concatStringsSep ":" rust-toolchains}"
    ];

  image = nix2container.buildImage {
    name = "lre-rs";
    maxLayers = 100;
    config = {inherit Env;};
    # Passthrough so that other images can reuse the environment.
    meta = {inherit Env;};

    # Don't set a tag here so that the image is tagged by its derivation hash.
    # tag = null;
  };
in {
  inherit lre-rs-configs-gen image;
  meta = {inherit Env;};
}
